import { reactive, inject, provide } from "vue";
import {
  createMutations,
  createActions,
  createGetters,
  createCommitFn,
  createDispatchFn,
} from "./creators";

class Store {
  constructor(options) {
    const { state, getters, mutations, actions } = options;

    const store = this;
    const { commit, dispatch } = store

    store._state = reactive({ data: state });
    // replacState -> _state 会转为 new _state -> reactive(new _state)
    store._mutations = Object.create(null);
    store._actions = Object.create(null);

    createMutations(store, mutations);
    createActions(store, actions);
    createGetters(store, getters);
    createCommitFn(store, commit);
    createDispatchFn(store, dispatch);
  }

  // store.state.xxx
  get state() {
    return this._state.data;
  }

  // static.a -> Store.a -> 静态函数 类的静态方法
  // store.commit store.dispatch
  commit(type, payload) {
    this._mutations[type](payload);
  }

  dispatch(type, payload) {
    this._actions[type](payload);
  }

  install(app) {
    // Store.prototype -》 原型链继承 -> 所有原型方法都是静态的
    // new Store -> install -> 不经过实例化
    app.provide("store", this);
    // 所有组件的模板中使用 $store
    app.config.globalProperties.$store = this;
  }
}

// export function createCommitFn(store, commit) {
//   store.commit = function (type, payload) {
//     commit.apply(store, [type, payload]);
//   };
// }

/**
 * 创建 Store 对象 -> use(stroe)
 *
 * createStore 必须要返回一个对象，并且有
 * install (app) {} 方法
 *
 * 每一次执行 -> 返回一个新的store
 * @param {*} options
 */
export const createStore = (options) => {
  // 高度集成的 -> 采用 类 实现
  // return {  // 字面量声明 -> new Object()
  //     install (app) {},
  //     getters,
  //     dispatch,
  //     commit,
  //     state
  // }
  // 生产出一个新的 store   -》 工厂模式

  return new Store(options);
};

export const useStore = () => {
  return inject("store"); // store 对象
};
